package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func main() {
	fmt.Println("===== Exec shell cmd Block =====")
	ExecShellBlock("id")

	fmt.Println("\n===== Exec shell cmd UNBlock =====")
	ExecShellUnblock("{ date +%T; echo 'sleep 2 seconds...'; sleep 2; date +%T; }")

	fmt.Println("\n===== get Shell output (stdout only) =====")
	GetShellOutput0("uname -r; ls yyy; exit 0")

	fmt.Println("===== get Shell output (stdout + stderr) =====")
	GetShellOutput1("hostname -I; ls xxx; exit 0")

	fmt.Println("===== get Shell output (set *Cmd.Stdout/Stderr) ======")
	GetShellOutput2("who")

	fmt.Println("=== go Pipe, like:\033[32mip a s wlan0 |awk '/inet/{print $2}'\033[0m ==")
	GetShellOutput3("ip a s dev wlan0", "awk '/net /{print $2}'")
}

func ExecShellBlock(cmd string) {
	var cmd0 *exec.Cmd
	cmd0 = exec.Command("/bin/bash", "-c", cmd)

	cmd0.Stdout = os.Stdout
	cmd0.Stderr = os.Stderr

	//Run() command as block mode
	err := cmd0.Run()
	if err != nil {
		log.Fatal(err)
	}
}

func ExecShellUnblock(cmd string) {
	var cmd1 *exec.Cmd = exec.Command("/bin/bash", "-c", cmd)
	cmd1.Stdout = os.Stdout
	cmd1.Stderr = os.Stderr

	err := cmd1.Start()
	if err != nil {
		log.Fatal(err)
	}
	cmd1.Wait()
}

func GetShellOutput0(cmd string) {
	var cmd0 *exec.Cmd
	buf := make([]byte, 1024)
	cmd0 = exec.Command("/bin/bash", "-c", cmd)

	buf, err := cmd0.Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(buf))
}

func GetShellOutput1(cmd string) {
	var cmd0 *exec.Cmd
	buf := make([]byte, 1024)
	cmd0 = exec.Command("/bin/bash", "-c", cmd)

	buf, err := cmd0.CombinedOutput()
	if err != nil {
		log.Println(err)
	}
	fmt.Println(string(buf))
}

func GetShellOutput2(cmd string) {
	var cmd0 *exec.Cmd
	cmd0 = exec.Command("/bin/bash", "-c", cmd)

	buf := new(bytes.Buffer)
	cmd0.Stdout = buf
	cmd0.Stderr = buf

	err := cmd0.Run()
	if err != nil {
		log.Println(err)
	}
	fmt.Println(buf)
}

func GetShellOutput3(c1, c2 string) {
	cmd0 := exec.Command("/bin/bash", "-c", c1)
	cmd1 := exec.Command("/bin/bash", "-c", c2)

	cmd1.Stdout = os.Stdout
	rd, err := cmd0.StdoutPipe()
	if err != nil {
		log.Fatalf("StdoutPipe: %s\n", err)
	}
	cmd1.Stdin = rd

	err = cmd0.Start()
	if err != nil {
		log.Fatal(err)
	}

	err = cmd1.Start()
	if err != nil {
		log.Fatal(err)
	}

	err = cmd0.Wait()
	if err != nil {
		log.Fatal(err)
	}

	err = cmd1.Wait()
	if err != nil {
		log.Fatal(err)
	}

}
